package com.bwie.system.config;

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitAdminConfig {

    @Value("${spring.rabbitmq.host}")
    private String host;
    @Value("${spring.rabbitmq.username}")
    private String username;
    @Value("${spring.rabbitmq.password}")
    private String password;
    @Value("${spring.rabbitmq.virtualhost}")
    private String virtualhost;

    // 我们使用 Spring 的 Bean 注解将我们声明的 connectionFactory 方法注入到 Spring 容器中
    @Bean
    public ConnectionFactory connectionFactory() {
        //我们使用 Spring-AMQP 中的 ConnectionFactory 类，来声明了一个名为 connectionFactory 的连接工厂方法，用于对 RabbitMQ 进行初始化
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        // 我们通过 cachingConnectionFactory 实例的 setAddresses 、setUsername 、setPassword 、setVirtualHost 方法来分别初始化 RabbitMQ Server 的服务地址、用户名、密码、虚拟主机
        connectionFactory.setAddresses(host);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualhost);
        // 配置发送确认回调时，次配置必须配置，否则即使在RabbitTemplate配置了ConfirmCallback也不会生效
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        connectionFactory.setPublisherReturns(true);
        //我们将填充好的 cachingConnectionFactory 实例进行返回，以初始化完成 RabbitMQ 客户端连接
        return connectionFactory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        // 我们 RabbitAdmin 类来声明了一个名为 rabbitAdmin 的方法，用来初始化 RabbitAdmin
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 我们首先根据上述的 connectionFactory 来实例化了一个 RabbitAdmin 实例；然后通过 rabbitAdmin 实例的 setAutoStartup 方法置位 true 来设置 RabbitAdmin 的自动启动；最后，我们将设置好的 rabbitAdmin 实例进行返回，以使用 RabbitAdmin
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }
}
